#ifndef SERVERCALCULATOR_HPP
#define SERVERCALCULATOR_HPP

#include <iostream>

#include "log.hpp"
#include "daemon.hpp"
#include "TcpSocket.hpp"
#include "CalRequest.hpp"
#include <signal.h>
#include <functional>

using func_t = std::function<std::string(std::string &package)>;

class TcpServer
{
public:
    TcpServer(uint16_t port, func_t callback) : port_(port), callback_(callback) {}

    bool Init()
    {
        listensock_.Socket();
        listensock_.Bind(port_);
        listensock_.Listen();
        return true;
    }

    bool Start()
    {
        Daemon();
        while (true)
        {
            signal(SIGCHLD, SIG_IGN);

            uint16_t clientport;
            std::string clientip;
            int sockfd = listensock_.Accept(&clientip, &clientport);
            if (sockfd < 0)
                continue;
            // 提供服务

            if (fork() == 0)
            {
                // child
                if (fork() == 0)
                {
                    // grandchild
                    listensock_.Close(); // 关闭不需要的套接字描述符
                    std::string in_stream;
                    while (true)
                    {
                        char buffer[128];
                        ssize_t n = read(sockfd, buffer, sizeof(buffer));
                        if (n > 0)
                        {
                            buffer[n] = 0;
                            in_stream += buffer;
                            while (true)
                            {
                                std::string info = callback_(in_stream);
                                if (info.empty())
                                {
                                    lg(WARNING, "Analysis fali");
                                    break;
                                }
                                lg(DEBUG, "Start() debug : %s", info.c_str());
                                write(sockfd, info.c_str(), info.size());
                            }
                        }
                    }
                    return true;
                }
                exit(0);
            }
            // parent
            close(sockfd);
        }
        return true;
    }

    ~TcpServer()
    {
        delete this;
    }

private:
    uint16_t port_;
    NetSocket listensock_;
    func_t callback_;
};

#endif